﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Tasks;
using System.IO;
using System.Text;
using System.Diagnostics;

namespace FlickrWP7.Core
{
    public class Uploader
    {
        HelperDelegate helperDelegateInstance;

        public string UploadResult {get;set;}
        byte[] contents;

        public enum SafetyLevel
        {
            Undefined = 0,
            Safe = 1,
            Moderate = 2,
            Restricted = 3
        }

        public enum ContentType
        {
            Undefined = 0,
            Photo = 1,
            Screenshot = 2,
            Other = 3
        }

        public enum Hidden
        {
            Undefined = 0,
            NotHidden = 1,
            IsHidden = 2
        }

        public enum IsPublic
        {
            Undefined = 2,
            No = 0,
            Yes = 1
        }

        public enum IsFriend
        {
            Undefined = 2,
            No = 0,
            Yes = 1
        }

        public enum IsFamily
        {
            Undefined = 2,
            No = 0,
            Yes = 1
        }

        public void Upload(string apiKey, string authToken, string signature, Stream photo, HelperDelegate helperDelegate,
            string title = "", string description = "", string[] tags = null, SafetyLevel safetyLevel = SafetyLevel.Undefined, ContentType contentType = ContentType.Undefined,
            Hidden hidden = Hidden.Undefined, IsPublic isPublic = IsPublic.Undefined, IsFriend isFriend = IsFriend.Undefined,
            IsFamily isFamily = IsFamily.Undefined)
        {
            helperDelegateInstance = helperDelegate;

            byte[] imageBytes = Core.ByteConverter.ConvertToByte(photo);

            string boundary = Guid.NewGuid().ToString();
            string header = "--" + boundary;
            string footer = "--" + boundary + "--";

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.flickr.com/services/upload/");
            request.ContentType = "multipart/form-data; boundary=" + boundary;

            StringBuilder headers = new StringBuilder();
            headers.AppendLine(header);
            headers.AppendLine("Content-Disposition: file; name=\"photo\"; filename=\"image1.jpg\"");
            headers.AppendLine("Content-Type: image/jpeg");
            headers.AppendLine();
            headers.AppendLine(Encoding.GetEncoding("iso-8859-1").GetString(imageBytes,0,imageBytes.Length));
            headers.AppendLine(header);

            headers.AppendLine("Content-Disposition: form-data; name=\"api_key\";");
            headers.AppendLine();
            headers.AppendLine(apiKey);
            headers.AppendLine(header);

            headers.AppendLine("Content-Disposition: form-data; name=\"auth_token\";");
            headers.AppendLine();
            headers.AppendLine(authToken);
            headers.AppendLine(header);

            headers.AppendLine("Content-Disposition: form-data; name=\"api_sig\";");
            headers.AppendLine();
            headers.AppendLine(signature);
            headers.AppendLine(header);

            if (title != "")
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"title\";");
                headers.AppendLine();
                headers.AppendLine(title);
                headers.AppendLine(header);
            }

            if (description != "")
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"description\";");
                headers.AppendLine();
                headers.AppendLine(description);
                headers.AppendLine(header);
            }

            if (tags != null)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"tags\";");
                headers.AppendLine();
                foreach (string tag in tags)
                    headers.Append(tag + " ");
                headers.AppendLine(header);
            }

            if (safetyLevel != SafetyLevel.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"safety_level\";");
                headers.AppendLine();
                headers.Append((int)safetyLevel);
                headers.AppendLine(header);
            }

            if (contentType != ContentType.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"content_type\";");
                headers.AppendLine();
                headers.Append((int)contentType);
                headers.AppendLine(header);
            }

            if (hidden != Hidden.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"hidden\";");
                headers.AppendLine();
                headers.Append((int)hidden);
                headers.AppendLine(header);
            }

            if (isPublic != IsPublic.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"is_public\";");
                headers.AppendLine();
                headers.Append((int)isPublic);
                headers.AppendLine(header);
            }

            if (isFamily != IsFamily.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"is_family\";");
                headers.AppendLine();
                headers.Append((int)isFamily);
                headers.AppendLine(header);
            }

            if (isFriend != IsFriend.Undefined)
            {
                headers.AppendLine("Content-Disposition: form-data; name=\"is_friend\";");
                headers.AppendLine();
                headers.Append((int)isFriend);
                headers.AppendLine(header);
            }

            headers.AppendLine(footer);

            contents = Encoding.GetEncoding("iso-8859-1").GetBytes(headers.ToString());

            request.Method = "POST";

            request.BeginGetRequestStream(new AsyncCallback(GetReqCallback), request);
        }

        void GetReqCallback(IAsyncResult asyncResult)
        {
            HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;
            Stream postStream = req.EndGetRequestStream(asyncResult);
            postStream.Write(contents, 0, contents.Length);
            postStream.Close();
            req.BeginGetResponse(new AsyncCallback(GetRespCallback), req);
        }

        void GetRespCallback(IAsyncResult asyncResult)
        {
            HttpWebRequest r = (HttpWebRequest)asyncResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)r.EndGetResponse(asyncResult);
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                UploadResult = reader.ReadToEnd();
            }

            helperDelegateInstance();
        }
               
    }
}
